package com.support.config;

import com.support.annotation.EnableRateLimiter;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Map;

/**
 * @author youshang
 * @date 2020/12/17 19:06
 **/
@Configuration
public class RateLimiterImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableRateLimiter.class.getName());
        Boolean flag = (Boolean) annotationAttributes.get("proxyTargetClass");

        //依赖于Spring底层实现，通常是Spring 内部使用，只需要有Spring aop的基础jar包就好，不需要导入spring-aspects jar包,但需要在注册Configuration中的Bean的时候需要添加@Role注解标识为早期的AdvisorBean
        //源码判断地址：InfrastructureAdvisorAutoProxyCreator.isEligibleAdvisorBean()
        AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
        // 使用registerAspectJAutoProxyCreatorIfNecessary 注入APC 不可以使用AspectJ原生注解 ，
        // 需要导入spring-aspects jar包 否则报错Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
//        AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(registry);
        //推荐使用这个，需要导入spring-aspects jar包，否则报错Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
//        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        if (flag) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(RateLimiterConfiguration.class);
        registry.registerBeanDefinition("rateLimiterConfiguration", genericBeanDefinition);
    }
}
